function genTile(x,y, terrainVal)

	if (getLevel() >= 4) then
		terrainVal["tileID"]=math.random(2) + 2
	else
		terrainVal["tileID"]=math.random(2)
	end

	terrainVal["FOV"] = false
	terrainVal["hasObject"] = false

	terrainVal["items"] = {}

	for i=1,10,1 do
		terrainVal["items"][i] = deepcopy(gameItems["empty"][1])
	end

	if (getLevel() >= 4) then return end

	-- player loc!
	if (x == characterLoc[1] and y == characterLoc[2])
		then return end

	-- Already a mob!
	if (getMobOnTile(x,y) ~= nil)
		then return end


	if (math.random(600) == 1 and isItemOnGround(x,y) == false) then 

		local randChance = math.min(getLevel(),3)
		if (math.random(2) == 1) then
			dropItem(gameItems["guns"][randChance],{x,y})
		else
			dropItem(gameItems["melee"][randChance],{x,y})
		end

		if (math.random(40) == 1) then
			dropItem(gameItems["ammo"][math.min(getLevel(),3)],{x,y})
		end

		if (math.random(20) == 1 ) then
			dropItem(gameItems["utils"][math.random(#gameItems.utils)],{x,y})
		end
		return
	end

	local mobiles = getMobsAlive()
	if (math.random(20) == 1 and getMobOnTile(x,y) ==  nil) then
		terrainVal["hasObject"] = true
		terrainVal["objectID"] = "TreeBase"
	elseif (mobiles == 0 and math.random(5) == 1 and getMobOnTile(x,y) ==  nil ) then
		spawnMob(x,y)
	elseif (math.random(100)==1 and mobiles < 6 and getMobOnTile(x,y) ==  nil) then
		spawnMob(x,y)
	end


end


function shiftTile(x,y,tx,ty)
	if (localTerrain[tx] == nil or localTerrain[tx][ty] == nil) then
		genTile(x,y,localTerrain[x][y])
	else
		localTerrain[x][y] = deepcopy(localTerrain[tx][ty])
	end
end

function getLevel()
	return math.floor( (600 - howFarLeft())/200) + 1
end

function checkMove(x,y)
	targetBlocked = isMoveBlocked(characterLoc[1]+x,characterLoc[2]+y)

	if (targetBlocked == true) then return false end
	return true
end


function gameShift(x,y)

	if (checkMove(x,y) == false) then
		addConsoleMessage("Your path is blocked in that direction")
		return
	end

	-- Clear mob FOV tags
	clearFOV()

	characterTargetLoc = {characterLoc[1]+x,characterLoc[2]+y}

	-- shift Mobs first (so that we can check if a mob is on a tile in generation)
	local mobList = activeMobs
    while mobList do
    	mobList.value.x = mobList.value.x -x
    	mobList.value.y = mobList.value.y -y

      	mobList = mobList.next
    end

    -- delete mobs that are far away
    -- Check first element
    while (activeMobs and outofRange(activeMobs.value.x,activeMobs.value.y)) do
    	activeMobs = activeMobs.next
    end

   	-- fix internal links
   	local mobList = activeMobs
    while mobList do

    	while  (mobList.next and outofRange(mobList.next.value.x,mobList.next.value.y) ) do
    	 	mobList.next = mobList.next.next
    	end

    	mobList = mobList.next
    end

    -- shift Terrain
	-- y shift
	if (y ~= 0) then
		for i = 1, worldData.size.x, 1 do
				if (y>0) then
					for j = 1,worldData.size.y,1 do
						shiftTile(i,j,i,j+y)
					end
				else
					for j = worldData.size.y,1,-1 do
						shiftTile(i,j,i,j+y)
					end
				end
		end
	end

	-- x shift
	if (x ~= 0)	then	
		for j = 1, worldData.size.y, 1 do
				if (x>0) then
					for i = 1,worldData.size.x,1 do
						shiftTile(i,j,i+x,j)
					end
				else
					for i = worldData.size.x,1,-1 do
						shiftTile(i,j,i+x,j)
					end
				end
		end
	end

    --update Distance
    distanceFromCenter[1] = distanceFromCenter[1] + 3*x
    if (x == 0) then
    	distanceFromCenter[2] = distanceFromCenter[2] + 3*y
    end

	characterTargetLoc = {characterLoc[1],characterLoc[2]}

	-- if there is something here, alert the guy
	if (isItemOnGround(characterLoc[1],characterLoc[2]) == true ) then
		addConsoleMessage("You see something lying in the snow here.","green")
	end

	gameTick();
end




function getMobOnTile(x,y)

-- Check for target Mob
	local mobList = activeMobs
    while mobList do

    	local mx = mobList.value.x
    	local my = mobList.value.y

    	if (mx == x and my == y and mobList.value.alive == true) then
    		return mobList.value
    	end

    	mobList = mobList.next
    end

    return nil

end



function outofRange(x,y)

	if (x < 0 or x > (worldData.size.x + 1)) then return true end
	if (x < 0 or x > (worldData.size.x + 1)) then return true end

	if (y < 0 or y > (worldData.size.y + 1)) then return true end
	if (y < 0 or y > (worldData.size.y + 1)) then return true end

	return false

end

function offPage(x,y)

	if (x < 1 or x > worldData.size.x ) then return true end
	if (x < 1 or x > worldData.size.x ) then return true end

	if (y < 1 or y > worldData.size.y ) then return true end
	if (y < 1 or y > worldData.size.y ) then return true end

	return false

end


function isObjectBlocking(x,y)

	if (targetTile.hasObject) then
		if (isBlocking[targetTile.objectID]) then
			return true
		end
	end 

	return false
end

function isMoveBlocked(x,y)

	if (localTerrain[x] == nil or localTerrain[x][y] == nil) then return true end

	-- Run off targetloc -> prevent mobs from walking onto the same tile as the player
	if (x == characterTargetLoc[1] and y == characterTargetLoc[2]) then return true end

	targetTile = localTerrain[x][y]

	if (isObjectBlocking(x,y) == true ) then return true end

	-- check for mobs
	local mobList = activeMobs
    while mobList do

    	if (mobList.value.alive == true) then

	    	if (mobList.value.x == x and mobList.value.y == y) then return true end

	    end

      	mobList = mobList.next
    end

	return false

end

-- Astar move test, differs from isMoveBlocked in that it's one step ahead
function isASBlocked(x,y)

	if (localTerrain[x] == nil or localTerrain[x][y] == nil) then return true end

	if (x == characterTargetLoc[1] and y == characterTargetLoc[2]) then return false end

	targetTile = localTerrain[x][y]

	if (targetTile.hasObject) then
		if (isBlocking[targetTile.objectID]) then
			return true
		end
	end 

	-- check for mobs
	local mobList = activeMobs
    while mobList do

    	if (mobList.value.alive == true) then

	    	if (mobList.value.isMoving == true) then
	    		local tx = mobList.value.x + mobList.value.heading.value[1]
	    		local ty = mobList.value.y + mobList.value.heading.value[2]
	    		if (tx == x and ty == y ) then return true end
	    	else
	    		if (mobList.value.x == x and mobList.value.y == y) then return true end
	    	end

	    end

      	mobList = mobList.next
    end

	return false

end



-- Pretty much the same as checkmove, but LOS only and without shift
function isLOSBlocked(x,y)
	-- off page
	if (localTerrain[x] == nil or localTerrain[x][y] == nil) then return true end

	targetTile = localTerrain[x][y]

	if (targetTile.hasObject) then
		if (isBlocking[targetTile.objectID]) then
			return true
		end
	end 

	return false
end





function howFarLeft()
	return  distanceTarget - ( math.abs(distanceFromCenter[1]) + math.abs(distanceFromCenter[2]) )
end






